🎖️GitЯра🎖️
Node / meshtastic / Meshtastic-Android / files / core / takserver / src / commonMain / kotlin / org / meshtastic / core / takserver / TAKServerManager.kt
Displaying Raw • Download
core/takserver/src/commonMain/kotlin/org/meshtastic/core/takserver/TAKServerManager.kt 3c7e1266f819f90df2bfca6717cd1df0414d6c3a (3c7e1266) Text, 5.31 KB
T8b949e/*
* Copyright (c) 2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tff7b72package T7ee787org.meshtastic.core.takserver
Tff7b72import T7ee787co.touchlab.kermit.Logger
Tff7b72import T7ee787kotlinx.coroutines.CoroutineScope
Tff7b72import T7ee787kotlinx.coroutines.flow.MutableSharedFlow
Tff7b72import T7ee787kotlinx.coroutines.flow.MutableStateFlow
Tff7b72import T7ee787kotlinx.coroutines.flow.SharedFlow
Tff7b72import T7ee787kotlinx.coroutines.flow.StateFlow
Tff7b72import T7ee787kotlinx.coroutines.flow.asSharedFlow
Tff7b72import T7ee787kotlinx.coroutines.flow.asStateFlow
Tff7b72import T7ee787kotlinx.coroutines.launch
Tff7b72import T7ee787kotlinx.coroutines.sync.Mutex
Tff7b72import T7ee787kotlinx.coroutines.sync.withLock
Tff7b72import T7ee787org.meshtastic.core.model.Node
Tff7b72interface T56d364TAKServerManager Tb4b4b4{
Tff7b72val Te6edf3isRunningTb4b4b4: Te6edf3StateFlowTff7b72<Tffa657BooleanTff7b72>
Tff7b72val Te6edf3connectionCountTb4b4b4: Te6edf3StateFlowTff7b72<Tffa657IntTff7b72>
Tff7b72val Te6edf3inboundMessagesTb4b4b4: Te6edf3SharedFlowTff7b72<Te6edf3CoTMessageTff7b72>
T8b949e/** Start the TAK server using [scope]. Port is fixed at [TAKServer] construction time. */
Tff7b72fun Td2a8ffstartTb4b4b4(Te6edf3scopeTb4b4b4: Te6edf3CoroutineScopeTb4b4b4)
Tff7b72fun Td2a8ffstopTb4b4b4(Tb4b4b4)
Tff7b72fun Td2a8ffbroadcastNodeTb4b4b4(Te6edf3nodeTb4b4b4: Te6edf3NodeTb4b4b4, Te6edf3teamTb4b4b4: Tffa657String Tff7b72= Te6edf3DEFAULT_TAK_TEAM_NAMETb4b4b4, Te6edf3roleTb4b4b4: Tffa657String Tff7b72= Te6edf3DEFAULT_TAK_ROLE_NAMETb4b4b4)
Tff7b72fun Td2a8ffbroadcastTb4b4b4(Te6edf3cotMessageTb4b4b4: Te6edf3CoTMessageTb4b4b4)
Tb4b4b4}
Tff7b72class T56d364TAKServerManagerImplTb4b4b4(Tff7b72private Tff7b72val Te6edf3takServerTb4b4b4: Te6edf3TAKServerTb4b4b4) Tb4b4b4: Te6edf3TAKServerManager Tb4b4b4{
Tff7b72private Tff7b72var Te6edf3scopeTb4b4b4: Te6edf3CoroutineScope? Tff7b72= Tff7b72null
Tff7b72private Tff7b72val Te6edf3lastBroadcastPositionsMutex Tff7b72= Te6edf3MutexTb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72val Te6edf3_isRunning Tff7b72= Te6edf3MutableStateFlowTb4b4b4(Tff7b72falseTb4b4b4)
Tff7b72override Tff7b72val Te6edf3isRunningTb4b4b4: Te6edf3StateFlowTff7b72<Tffa657BooleanTff7b72> Tff7b72= Te6edf3_isRunningTb4b4b4.Te6edf3asStateFlowTb4b4b4(Tb4b4b4)
T8b949e// Mirror TAKServer's event-driven connection count — no polling needed
Tff7b72override Tff7b72val Te6edf3connectionCountTb4b4b4: Te6edf3StateFlowTff7b72<Tffa657IntTff7b72> Tff7b72= Te6edf3takServerTb4b4b4.Te6edf3connectionCount
Tff7b72private Tff7b72val Te6edf3_inboundMessages Tff7b72= Te6edf3MutableSharedFlowTff7b72<Te6edf3CoTMessageTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72override Tff7b72val Te6edf3inboundMessagesTb4b4b4: Te6edf3SharedFlowTff7b72<Te6edf3CoTMessageTff7b72> Tff7b72= Te6edf3_inboundMessagesTb4b4b4.Te6edf3asSharedFlowTb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72var Te6edf3lastBroadcastPositions Tff7b72= Te6edf3mutableMapOfTff7b72<Tffa657IntTb4b4b4, Tffa657IntTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72override Tff7b72fun Td2a8ffstartTb4b4b4(Te6edf3scopeTb4b4b4: Te6edf3CoroutineScopeTb4b4b4) Tb4b4b4{
Tff7b72thisTb4b4b4.Te6edf3scope Tff7b72= Te6edf3scope
Tff7b72if Tb4b4b4(Te6edf3_isRunningTb4b4b4.Te6edf3valueTb4b4b4) Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3w Tb4b4b4{ Ta5d6ff"Ta5d6ffTAKServerManager already runningTa5d6ff" Tb4b4b4}
Tff7b72return
Tb4b4b4}
Te6edf3scopeTb4b4b4.Te6edf3launch Tb4b4b4{
T8b949e// Wire up inbound message handler BEFORE starting so no messages are lost
Te6edf3takServerTb4b4b4.Te6edf3onMessage Tff7b72= Tb4b4b4{ Te6edf3cotMessage Tff7b72-Tff7b72> Te6edf3scopeTb4b4b4.Te6edf3launch Tb4b4b4{ Te6edf3_inboundMessagesTb4b4b4.Te6edf3emitTb4b4b4(Te6edf3cotMessageTb4b4b4) Tb4b4b4} Tb4b4b4}
Tff7b72val Te6edf3result Tff7b72= Te6edf3takServerTb4b4b4.Te6edf3startTb4b4b4(Te6edf3scopeTb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3resultTb4b4b4.Te6edf3isSuccessTb4b4b4) Tb4b4b4{
Te6edf3_isRunningTb4b4b4.Te6edf3value Tff7b72= Tff7b72true
Te6edf3LoggerTb4b4b4.Te6edf3i Tb4b4b4{ Ta5d6ff"Ta5d6ffTAK Server startedTa5d6ff" Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3eTb4b4b4(Te6edf3resultTb4b4b4.Te6edf3exceptionOrNullTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{ Ta5d6ff"Ta5d6ffFailed to start TAK ServerTa5d6ff" Tb4b4b4}
T8b949e// Clear onMessage if start failed so we don't hold a reference unnecessarily
Te6edf3takServerTb4b4b4.Te6edf3onMessage Tff7b72= Tff7b72null
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffstopTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3takServerTb4b4b4.Te6edf3stopTb4b4b4(Tb4b4b4)
Te6edf3takServerTb4b4b4.Te6edf3onMessage Tff7b72= Tff7b72null
Te6edf3_isRunningTb4b4b4.Te6edf3value Tff7b72= Tff7b72false
Te6edf3scope Tff7b72= Tff7b72null
Te6edf3LoggerTb4b4b4.Te6edf3i Tb4b4b4{ Ta5d6ff"Ta5d6ffTAK Server stoppedTa5d6ff" Tb4b4b4}
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffbroadcastNodeTb4b4b4(Te6edf3nodeTb4b4b4: Te6edf3NodeTb4b4b4, Te6edf3teamTb4b4b4: Tffa657StringTb4b4b4, Te6edf3roleTb4b4b4: Tffa657StringTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3_isRunningTb4b4b4.Te6edf3valueTb4b4b4) Tff7b72return
Tff7b72val Te6edf3currentScope Tff7b72= Te6edf3scope Tff7b72?: Tff7b72return
Te6edf3currentScopeTb4b4b4.Te6edf3launch Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3takServerTb4b4b4.Te6edf3hasConnectionsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72returnTf0883e@launch
Tff7b72val Te6edf3position Tff7b72= Te6edf3nodeTb4b4b4.Te6edf3validPosition
Tff7b72if Tb4b4b4(Te6edf3position Tff7b72=Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
Te6edf3broadcastNodeInfoOnlyTb4b4b4(Te6edf3nodeTb4b4b4, Te6edf3teamTb4b4b4, Te6edf3roleTb4b4b4)
Tff7b72returnTf0883e@launch
Tb4b4b4}
Tff7b72val Te6edf3shouldBroadcast Tff7b72=
Te6edf3lastBroadcastPositionsMutexTb4b4b4.Te6edf3withLock Tb4b4b4{
Tff7b72val Te6edf3last Tff7b72= Te6edf3lastBroadcastPositionsTff7b72[Te6edf3nodeTb4b4b4.Te6edf3numTff7b72]
Tff7b72if Tb4b4b4(Te6edf3positionTb4b4b4.Te6edf3time Tff7b72=Tff7b72= Te6edf3lastTb4b4b4) Tb4b4b4{
Tff7b72false
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3lastBroadcastPositionsTff7b72[Te6edf3nodeTb4b4b4.Te6edf3numTff7b72] Tff7b72= Te6edf3positionTb4b4b4.Te6edf3time
Tff7b72true
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3shouldBroadcastTb4b4b4) Tff7b72returnTf0883e@launch
Tff7b72val Te6edf3cotMessage Tff7b72=
Te6edf3positionTb4b4b4.Te6edf3toCoTMessageTb4b4b4(
Te6edf3uid Tff7b72= Te6edf3nodeTb4b4b4.Te6edf3userTb4b4b4.Te6edf3idTb4b4b4,
Te6edf3callsign Tff7b72= Te6edf3nodeTb4b4b4.Te6edf3userTb4b4b4.Te6edf3toTakCallsignTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3team Tff7b72= Te6edf3teamTb4b4b4,
Te6edf3role Tff7b72= Te6edf3roleTb4b4b4,
Te6edf3battery Tff7b72= Te6edf3nodeTb4b4b4.Te6edf3deviceMetricsTb4b4b4.Te6edf3battery_level Tff7b72?: T79c0ff1T79c0ff0T79c0ff0Tb4b4b4,
Tb4b4b4)
Te6edf3takServerTb4b4b4.Te6edf3broadcastTb4b4b4(Te6edf3cotMessageTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffbroadcastNodeInfoOnlyTb4b4b4(Te6edf3nodeTb4b4b4: Te6edf3NodeTb4b4b4, Te6edf3teamTb4b4b4: Tffa657StringTb4b4b4, Te6edf3roleTb4b4b4: Tffa657StringTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3currentScope Tff7b72= Te6edf3scope Tff7b72?: Tff7b72return
Tff7b72val Te6edf3cotMessage Tff7b72=
Te6edf3nodeTb4b4b4.Te6edf3userTb4b4b4.Te6edf3toCoTMessageTb4b4b4(
Te6edf3position Tff7b72= Tff7b72nullTb4b4b4,
Te6edf3team Tff7b72= Te6edf3teamTb4b4b4,
Te6edf3role Tff7b72= Te6edf3roleTb4b4b4,
Te6edf3battery Tff7b72= Te6edf3nodeTb4b4b4.Te6edf3deviceMetricsTb4b4b4.Te6edf3battery_level Tff7b72?: T79c0ff1T79c0ff0T79c0ff0Tb4b4b4,
Tb4b4b4)
Te6edf3currentScopeTb4b4b4.Te6edf3launch Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3takServerTb4b4b4.Te6edf3hasConnectionsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72returnTf0883e@launch
Te6edf3takServerTb4b4b4.Te6edf3broadcastTb4b4b4(Te6edf3cotMessageTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffbroadcastTb4b4b4(Te6edf3cotMessageTb4b4b4: Te6edf3CoTMessageTb4b4b4) Tb4b4b4{
Te6edf3scopeTff7b72?.Te6edf3launch Tb4b4b4{ Te6edf3takServerTb4b4b4.Te6edf3broadcastTb4b4b4(Te6edf3cotMessageTb4b4b4) Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Served by rngit 1.5.3 - Generated in 0.06s